<?php
/**
 * 
 * Table model for invitations
 * 
 * @category Abovo
 * 
 * @package Abovo_Model_Invites
 * 
 * @author Antti Holvikari <anttih@gmail.com>
 * 
 * @license http://opensource.org/licenses/gpl-license.php GPL
 * 
 */

/**
 * 
 * Table model for invitations
 * 
 * @category Abovo
 * 
 * @package Abovo_Model_Invites
 * 
 */
class Abovo_Model_Invites extends Abovo_Sql_Table {
    
    /**
     * 
     * Status indicating that invitation
     * is pending for approval
     * 
     * @const int 0
     * 
     */
    const STATUS_PENDING = 0;
    
    /**
     * 
     * Status indicating that invitation
     * has been approved
     * 
     * @const int 1
     * 
     */
    const STATUS_APPROVED = 1;
    
    /**
     * 
     * Fetches all invitations that are pending
     * 
     * @param string $order SQL order clause
     * 
     * @return Solar_Sql_Rowset
     * 
     */
    public function fetchAllPending($order = null)
    {
        return $this->fetchAll('status = ' . self::STATUS_PENDING, $order);
    }
    
    /**
     * 
     * Fetches all invitations that are approved
     * 
     * @param string $order SQL order clause
     * 
     * @return Solar_Sql_Rowset
     * 
     */
    public function fetchAllApproved($order = null)
    {
        return $this->fetchAll("status = " . self::STATUS_APPROVED, $order);
    }
    
    /**
     * 
     * Creates an invitation
     * 
     * @param string $email Email to which send the invitation
     * 
     * @param $handle User handle that sent this invitation
     * 
     * @return array Data as inserted
     * 
     */
    public function create($email, $handle)
    {
        // create a hash for the invite
        // @todo make sure this is a good algo
        $hash = hash('md5', microtime() . rand());
        
        $data = array(
            'email'  => $email,
            'handle' => $handle,
            'hash'   => $hash,
            'status' => self::STATUS_PENDING,
        );
        
        return $this->insert($data);
    }
    
    /**
     * 
     * Approve an invitation by hash
     * 
     * @param string $hash Invitation hash
     * 
     * @return void
     * 
     */
    public function approve($hash)
    {
        $data = array(
            'status' => self::STATUS_APPROVED,
        );
        $where = array("hash = ?" => $hash);
        return $this->update($data, $where);
    }
    
    /**
     * 
     * Checks if hash is valid
     * 
     * @return bool
     * 
     */
    public function isValid($hash)
    {
        if (strlen((string) $hash) != 32) {
            return false;
        }
        
        $sel = Solar::factory('Solar_Sql_Select');
        
        $ok = $sel->from($this->_name, 'count(id)')
                  ->where('hash = ?', $hash)
                  ->where('status = ' . self::STATUS_PENDING)
                  ->fetch('value');
        
        return (bool) $ok;
    }
    
    /**
     * 
     * Removes the invite from the table
     * 
     * @return bool
     * 
     */
    public function clean($email, $hash)
    {
        $this->delete(array(
            'email = ?' => $email,
            'hash = ?'  => $hash
        ));
    }
    
    /**
     * 
     * Table schema
     * 
     * @return void
     * 
     */
    protected function _setup()
    {
        // Table name
        $this->_name = 'invites';
        
        // user who sent this invite
        $this->_col['handle'] = array(
            'type'    => 'varchar',
            'size'    => '15',
            'require' => true,
        );
        
        // Invites email address
        $this->_col['email'] = array(
            'type'    => 'varchar',
            'size'    => 50,
            'require' => true,
            'filter'  => 'email',
        );
        
        // Hash of the time when invite was sent
        $this->_col['hash'] = array(
            'type'    => 'varchar',
            'size'    => 32,
            'require' => true,
        );
        
        // status of the invitation
        $this->_col['status'] = array(
            'type'    => 'int',
            'size'    => 1,
            'require' => true,
            'default' => self::STATUS_PENDING,
        );
        
        // Make sure sql is available
        if(! Solar::isRegistered('sql')) {
            Solar::register('sql', Solar::factory('Solar_Sql'));
        }
    }
}
